use crate::components::enums::AppMode;
use crate::util::{self};
use ratatui::{Frame, prelude::*, widgets::*};

use crate::components::component::App;

use super::render::choose_color;

// 渲染tcp/udp ui
pub fn ui(f: &mut Frame, app: &mut App, chunks: &[Rect]) {
    // 1. 连接面板
    let conn_chunks = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
        .split(chunks[0]);

    // Protocol
    let protocol_block_title =
        crate::ui::render::create_style_title_default(" Protocol", vec!["P"]);
    let protocol_block = Block::default()
        .title(protocol_block_title)
        .borders(Borders::ALL)
        .border_style(choose_color(false))
        .border_type(BorderType::Rounded);
    let protocol_name: &str = app.protocol.into();
    let protocol_text = Paragraph::new(protocol_name).block(protocol_block);
    f.render_widget(protocol_text, conn_chunks[0]);

    // Server Address
    let is_editing_addr = app.mode == AppMode::EditingAddress;
    let addr_text_content: &str = if is_editing_addr {
        &app.current_input
    } else {
        &app.server_addr
    };
    let addr_block_title =
        crate::ui::render::create_style_title_default(" Server Address", vec!["S"]);
    let addr_block = Block::default()
        .title(addr_block_title)
        .borders(Borders::ALL)
        .border_type(BorderType::Rounded)
        .border_style(choose_color(is_editing_addr));
    let addr_text = Paragraph::new(addr_text_content).block(addr_block);
    f.render_widget(addr_text, conn_chunks[1]);
    if is_editing_addr {
        util::set_cursor_position(
            f,
            conn_chunks[1].x + 1 + addr_text_content.chars().count() as u16,
            conn_chunks[1].y + 1,
        );
    }

    // 2. 发送数据区
    let is_editing_data = app.mode == AppMode::EditingData;
    let data_text_content: &str = if is_editing_data {
        &app.current_input
    } else {
        &app.request_data
    };
    let data_block_title =
        crate::ui::render::create_style_title_default(" Request Data ", vec!["R"]);
    let data_block = Block::default()
        .title(data_block_title)
        .borders(Borders::ALL)
        .border_type(BorderType::Rounded)
        .border_style(choose_color(is_editing_data));
    let input_text = Paragraph::new(data_text_content).block(data_block);
    f.render_widget(input_text, chunks[1]);
    if is_editing_data {
        util::set_cursor_position(
            f,
            chunks[1].x + 1 + data_text_content.chars().count() as u16,
            chunks[1].y + 1,
        );
    }

    // 1. 创建基础 Block，只包含左侧标题
    let recv_block = Block::default()
        .title(" Response Data ('c' to copy)")
        .borders(Borders::ALL)
        .border_style(choose_color(false))
        .border_type(BorderType::Rounded);

    // 2. 根据状态决定覆盖在标题行上的提示文字
    let placeholder_text = if app.is_not_connected() {
        "Press <Space> to connect."
    } else {
        "Press <Space> to send data, 'd' to disconnect."
    };
    let placeholder_paragraph = Paragraph::new(placeholder_text)
        .style(Style::default().fg(Color::DarkGray))
        .alignment(Alignment::Center);

    // 在同一个rect渲染2个标题
    // 3. 先渲染边框和左标题
    f.render_widget(recv_block.clone(), chunks[2]);
    // 4. 在同一区域覆盖上居中的提示文字，形成双标题行的效果
    f.render_widget(placeholder_paragraph, chunks[2]);

    // 5. 如果有接收到的数据，将其渲染到 Block 的 "内部" 区域
    if !app.received_data.is_empty() {
        // 获取 Block 边框和标题下方的内部区域
        let inner_area = recv_block.inner(chunks[2]);

        let data_paragraph = Paragraph::new(app.received_data.as_str())
            .style(
                Style::default()
                    .fg(Color::Blue)
                    .add_modifier(Modifier::BOLD),
            )
            .wrap(Wrap { trim: true })
            .scroll((app.scroll_position as u16, 0));

        // 将数据只渲染在内部区域
        f.render_widget(data_paragraph, inner_area);
    }

    // 4. 日志区
    let log_block = Block::default()
        .title(" Logs ")
        .borders(Borders::ALL)
        .border_style(choose_color(false))
        .border_type(BorderType::Rounded);
    let log_text = Paragraph::new(app.logs.clone()).block(log_block);
    f.render_widget(log_text, chunks[3]);
}
